package cn.jbolt.core.kit;

import cn.jbolt.core.api.JBoltApiKit;
import cn.jbolt.core.api.JBoltApiRet;
import cn.jbolt.core.base.JBoltRequestType;
import cn.jbolt.core.consts.JBoltConst;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.render.JsonRender;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import com.jfinal.render.RenderManager;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JBoltHandlerKit {
	private static final Log JBOLT_API_LOG = Log.getLog("JBoltApiLog");
	private static final Log LOG = Log.getLog(JBoltControllerKit.class);
	private JBoltHandlerKit(){}

	public static void renderError404(String view, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;
		response.setStatus(HttpServletResponse.SC_NOT_FOUND);
		RenderManager.me().getRenderFactory().getRender(view).setContext(request, response).render();
	}
	public static void renderError500(String view, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;
		response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		RenderManager.me().getRenderFactory().getRender(view).setContext(request, response).render();
	}

	public static void renderError404(HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;
		RenderManager.me().getRenderFactory().getErrorRender(404).setContext(request, response).render();
	}

	public static void renderError500(HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;
		RenderManager.me().getRenderFactory().getErrorRender(500).setContext(request, response).render();
	}

	public static void redirect301(String url, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;
		String queryString = request.getQueryString();
		if (queryString != null) {
			if (url.indexOf('?') == -1) {
				url = url + "?" + queryString;
			} else {
				url = url + "&" + queryString;
			}
		}

		response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
		response.setHeader("Location", url);
		response.setHeader("Connection", "close");
	}

	public static void redirect(String url, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
		isHandled[0] = true;

		String queryString = request.getQueryString();
		if (queryString != null) {
			if (url.indexOf('?') == -1) {
				url = url + "?" + queryString;
			} else {
				url = url + "&" + queryString;
			}
		}

		try {
			response.sendRedirect(url);	// always 302
		} catch (IOException e) {
			throw new RenderException(e);
		}
	}


	public static void renderFail(String msg,HttpServletRequest request, HttpServletResponse response,boolean[] isHandled) {
		renderFail(msg, null, request, response, isHandled);
	}
	public static void renderFail(String msg,Object data,HttpServletRequest request, HttpServletResponse response,boolean[] isHandled) {
		isHandled[0] = true;
		Object rqTypeObj = request.getAttribute(JBoltConst.RQKEY_JB_RQTYPE);
		if(rqTypeObj == null) {
			renderError404(request, response,isHandled);
			return;
		}
		String rqType = rqTypeObj.toString().trim();
		if (StrKit.isBlank(rqType)) {
			renderPageFail(request,response,msg);
			return;
		}
		switch (rqType) {
		case JBoltRequestType.JBOLTAPI:
			renderJBoltApiFail(request,response,msg, data);
			break;
		case JBoltRequestType.AJAX:
			renderJsonFail(request, response,msg, data);
			break;
		case JBoltRequestType.JSON:
			renderJsonFail(request, response,msg, data);
			break;
		case JBoltRequestType.PJAX:
			renderPjaxFail(request,response,msg);
			break;
		case JBoltRequestType.AJAXPORTAL:
			renderAjaxPortalFail(request,response, msg);
			break;
		case JBoltRequestType.DIALOG:
			renderDialogFail(request,response, msg);
			break;
		case JBoltRequestType.IFRAME:
			renderIframeFail(request,response, msg);
			break;
		case JBoltRequestType.NORMAL:
			renderPageFail(request,response, msg);
			break;
		case JBoltRequestType.NULL:
			renderJsonFail(request,response, msg, data);
			break;
		default:
			renderJsonFail(request,response, msg, data);
			break;
		}
	}

	private static void renderAjaxPortalFail(HttpServletRequest request, HttpServletResponse response, String msg) {
		setMsg(request,msg);
		renderView(request,response,"/_view/_admin/common/msg/portalerror.html");
	}

	private static void renderDialogFail(HttpServletRequest request,HttpServletResponse response, String msg) {
		setMsg(request,msg);
		renderView(request,response,"/_view/_admin/common/msg/dialogerror.html");
	}

	public static void renderIframeFail(HttpServletRequest request,HttpServletResponse response, String msg) {
		setMsg(request,msg);
		renderView(request,response,"/_view/_admin/common/msg/iframeerror.html");
	}

	public static void renderPjaxFail(HttpServletRequest request, HttpServletResponse response, String msg) {
		setMsg(request,msg);
		renderView(request,response,"/_view/_admin/common/msg/pjaxerror.html");
	}

	public static void renderJBoltApiFail(HttpServletRequest request, HttpServletResponse response, String msg, Object data) {
		renderJBoltApiRet(request,response,JBoltApiRet.API_FAIL(JBoltApiKit.getApplication(), msg));
	}

	public static void renderJBoltApiRet(HttpServletRequest request, HttpServletResponse response,JBoltApiRet jboltApiRet) {
		if (jboltApiRet.isFail()) {
			// 单独处理错误日志
			JBOLT_API_LOG.error("[{}-[{}]-{}]", jboltApiRet.getMsg(), jboltApiRet.getCode(),
					JsonKit.toJson(jboltApiRet.getData()));
		}
		renderJson(request,response,jboltApiRet);
	}

	public static void renderJson(HttpServletRequest request, HttpServletResponse response,Object object) {
		Render render = object instanceof JsonRender ? (JsonRender)object : RenderManager.me().getRenderFactory().getJsonRender(object);
		if(render!=null) {
			render.setContext(request, response).render();
		}
	}

	/**
	 * 链接页面跳转 错误信息显示
	 * @param request
	 * @param response
	 * @param msg
	 */
	public static void renderPageFail(HttpServletRequest request, HttpServletResponse response,String msg) {
		setMsg(request,msg);
		renderView(request,response,"/_view/_admin/common/msg/pagefail.html");
	}

	private static void setMsg(HttpServletRequest request, String msg) {
		request.setAttribute("msg",msg);
	}

	/**
	 * 跳转view
	 * @param request
	 * @param response
	 * @param view
	 */
	public static void renderView(HttpServletRequest request, HttpServletResponse response, String view) {
		response.setStatus(HttpServletResponse.SC_OK);
		RenderManager.me().getRenderFactory().getRender(view).setContext(request, response).render();
	}

	/**
	 * 链接页面跳转 错误信息显示 H5移动场景使用
	 *
	 * @param request
	 * @param response
	 * @param msg
	 */
	public static void renderH5PageFail(HttpServletRequest request, HttpServletResponse response,String msg) {
		setMsg(request,msg);
		renderView(request, response, "/_view/_common/h5/msg/pagefail.html");
	}


	/**
	 * 返回失败信息 json格式
	 * @param request
	 * @param response
	 * @param msg
	 * @param data
	 */
	public static void renderJsonFail(HttpServletRequest request, HttpServletResponse response,String msg, Object data) {
		renderJson(request, response, Ret.fail(msg).setIfNotNull("data", data));
	}

}
